package com.bluebench.bigul.service.processor;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

import com.bluebench.bigul.domain.Element;
import com.bluebench.bigul.domain.Element.Attribute;
import com.bluebench.bigul.domain.Element.Parameter;
import com.bluebench.bigul.domain.ElementType;
import com.bluebench.bigul.domain.Tag;
import com.bluebench.bigul.domain.Types;
import com.bluebench.bigul.exception.GraphicInitializationException;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.ListItem;

public class CollectionProcessor extends GenericProcessor{
	
	private Tag tag; 	
	private Object collection; //parameter collection to be passed to the attribute (listitems)
	@Override
	public Object process() throws SecurityException, IllegalArgumentException,
			ClassNotFoundException, NoSuchMethodException,
			IllegalAccessException, InvocationTargetException,
			InstantiationException, NoSuchFieldException, GraphicInitializationException {
		
		ArrayList<Parameter> parameterList = (ArrayList)collection;
		ArrayList<com.itextpdf.text.Element> listItems = new ArrayList<com.itextpdf.text.Element>();
		ArrayList list = new ArrayList(); 
		String type = tag.getType();
		for(Parameter p : parameterList){ //p = a parameter enclosed within <collection></collection>
			/*
			 * Potential Problem
			 * -----------------
			 * For normal cases (i.e. : non-nested cases) value is instance of String 
			 * but for nested cases value is instance of ListItem, for which there is 
			 * no condition defined.
			 * 
			 *  Parameter type has no role to play in identifying the type of the value.
			 *  
			 */
			Object value = p.getValue();
			
			 if(value instanceof String){
				 
				if(type.equals("collection")){
					String itemVal = (String)value;
					listItems.add(new ListItem(itemVal));
				}else if(type.equals("arraylist")){					
					p.setProcessor(GenericProcessor.getInstance(PARAMETER_PROCESSOR));
					Object obj = p.process();
					list.add(obj);
				}
				
			}else if(value instanceof Integer || value instanceof Float){
				p.setProcessor(GenericProcessor.getInstance(PARAMETER_PROCESSOR));
				Object obj = p.process();
				list.add(obj);
			}else if(value instanceof Element){
				
				Element e = (Element)value;
				e.setProcessor(GenericProcessor.getInstance(ELEMENT_PROCESSOR));
				Object obj = e.process();
				if(obj instanceof Chunk){
					listItems.add(new ListItem((Chunk)obj));
				}else if(obj instanceof com.itextpdf.text.List){
					listItems.add((com.itextpdf.text.List)obj);
				}else{
					list.add(obj);
				}
				/*
				 * TODO : Potential Problem - Processed pointa, pointb, pointc.. elements not added to the list variable as list.add(obj) resulting in an empty collection.
				 */
				
			}
		}
		
		if(type.equals("collection")){
			return listItems;
		}else if(type.equals("arraylist")){
			return list;
		}
		
		return listItems;		
	}

	@Override
	public void set(Tag t) {
		tag = t;		
	}	
	
	public void setCollection(Object collection){
		this.collection = collection;
	}

	
	

}
